package com.activenetwork.smlite.page.rfp.RfpMaintenanceView;

import java.math.BigDecimal;
import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.activenetwork.custom.other.XCheckbox;
import com.activenetwork.custom.uielement.UIElement;
import com.activenetwork.custom.uielement.decorate.InJson;
import com.activenetwork.schema.model.rfp.MeetingSpaceInfoType;
import com.activenetwork.schema.model.rfp.RfpMeetingSpaceType;
import com.activenetwork.smlite.page.rfp.RfpBasicsSubview;
import com.activenetwork.smlite.snippet.RfpDateCalculator;
import com.activenetwork.smlite.snippet.RfpDay;
import com.activenetwork.util.DateUtil;
import com.activenetwork.util.EnvContext;
import com.activenetwork.util.PageLoader;
import com.activenetwork.util.RandomString;
import com.activenetwork.util.WaitUtil;
import com.activenetwork.util.dropdownmenu.DropdownMenu;
import com.activenetwork.util.dropdownmenu.TimeDropdownMenu;
import com.google.common.collect.Lists;

public class RfpEventSpace extends RfpBasicsSubview {
	private Logger logger = LoggerFactory.getLogger(RfpEventSpace.class);
	
	@InJson
	private UIElement additionInformationHeader;
	@InJson
	private UIElement eventSpaceComment;
	
	/**
	 * Parse meeting space category & day index, return list representing one day's all meeting space data
	 * category: pre - stands for preceding shoulder event space
	 * category: post - stands for following shoulder event space
	 * category: origin - stands for original shoulder event space 
	 * dayIndex: to identify which day this piece of meeting space data belongs to
	 * @param meetingSpace
	 * @param category
	 * @return
	 */
	private List<MeetingSpaceInfoType> getMeetingSpaceData(RfpMeetingSpaceType meetingSpace, String category, int rowIndex, RfpDateCalculator calculator){
		// Get all the meeting space xml node
		List<MeetingSpaceInfoType> spaces = meetingSpace.getMeetingSpaceInfo();
		List<MeetingSpaceInfoType> targetList = Lists.newArrayList();
		// Loop to get the corresponding meeting space node
		// Recalculate each day's day index to match the actual row index of the day on the page
		int matchRowIndex = -1;
		for(MeetingSpaceInfoType sp : spaces){
			if(category.equals("pre")){
				matchRowIndex =  sp.getDayIndex();
			}
			if(category.equals("origin")){
				matchRowIndex =  sp.getDayIndex() + calculator.rfpLength("pre");
			}
			if(category.equals("post")){
				matchRowIndex =  sp.getDayIndex() + calculator.rfpLength("pre") + calculator.rfpLength("origin");
			}
			if(sp.getCategory().equals(category) && matchRowIndex == rowIndex){
				targetList.add(sp);
			}
		}
		return targetList;
	} 
	
	
	/**
	 * Setup event space preceding days
	 * @param meetingSpaces
	 * @param calculator
	 * @return
	 */
	public RfpEventSpace setPrecedingShoulderEventSpace(RfpMeetingSpaceType meetingSpaces, RfpDateCalculator calculator){
		List<RfpDay> precedingDays = calculator.getRfpDays("pre");
		RfpEventSpace instance = PageLoader.load(RfpEventSpace.class);
		for(RfpDay rfpday : precedingDays){
			// Get this day event space data
			List<MeetingSpaceInfoType> ms_oneday_data = getMeetingSpaceData(meetingSpaces, "pre", rfpday.getRowIndex(), calculator);
			// Setup meeting space for this day
			for(MeetingSpaceInfoType data : ms_oneday_data){
				instance = instance.setEventSpace(data, rfpday.getRowIndex()-1);
			}
		}
		return instance;
	}
	/**
	 * Setup event space origin days
	 * @param meetingSpaces
	 * @param calculator
	 * @return
	 */
	public RfpEventSpace setOriginEventSpace(RfpMeetingSpaceType meetingSpaces, RfpDateCalculator calculator){
		List<RfpDay> originDays = calculator.getRfpDays("origin");
		RfpEventSpace instance = PageLoader.load(RfpEventSpace.class);
		for(RfpDay rfpday : originDays){
			// Get this day event space data
			List<MeetingSpaceInfoType> ms_oneday_data = getMeetingSpaceData(meetingSpaces, "origin", rfpday.getRowIndex(), calculator);
			// Setup meeting space for this day
			for(MeetingSpaceInfoType data : ms_oneday_data){
				instance = instance.setEventSpace(data, rfpday.getRowIndex()-1);
			}
		}
		return instance;
	}
	/**
	 * Setup event space following days
	 * @param meetingSpaces
	 * @param calculator
	 * @return
	 */
	public RfpEventSpace setFollowingShoulderEventSpace(RfpMeetingSpaceType meetingSpaces, RfpDateCalculator calculator){
		List<RfpDay> followingDays = calculator.getRfpDays("post");
		RfpEventSpace instance = PageLoader.load(RfpEventSpace.class);
		for(RfpDay rfpday : followingDays){
			// Get this day event space data
			List<MeetingSpaceInfoType> ms_oneday_data = getMeetingSpaceData(meetingSpaces, "post", rfpday.getRowIndex(), calculator);
			// Setup meeting space for this day
			for(MeetingSpaceInfoType data : ms_oneday_data){
				instance = instance.setEventSpace(data, rfpday.getRowIndex()-1);
			}
		}
		return instance;
	}
	/**
	 * Setup one event space record under one random day and copy to all days
	 * @param meetingSpaces
	 * @param calculator
	 * @return
	 */
	public RfpEventSpace setCopyAllDayEventSpace(RfpMeetingSpaceType meetingSpaces, RfpDateCalculator calculator){
		RfpEventSpace instance = PageLoader.load(RfpEventSpace.class);
		List<MeetingSpaceInfoType> spaces = meetingSpaces.getMeetingSpaceInfo();
		for(MeetingSpaceInfoType sp : spaces){
			if(sp.getCategory().equals("all")){
				instance = instance.setEventSpace(sp, RandomString.generateRandomInt(calculator.rfpLength()));
			}
		}
		return instance;
	}
	
	/**
	 * Setup one certain day event space
	 * @param meetingSpace
	 * @return
	 */
	public RfpEventSpace setEventSpace(MeetingSpaceInfoType eventSpace, int dayIndex){
		// find the root div for each day
		WebDriver driver = EnvContext.webDriverTL.get();
		By rootDivBy = By.cssSelector("div.autotest-grid-RfpMeetingRoomsSubview-rfpmeetingroomsgrid[data-nexus-groupgrid-index='" + dayIndex + "']");
		WebElement rootDiv = driver.findElement(rootDivBy);
		
		String dayInfo = rootDiv.findElement(By.xpath(".//div[@class='section-header']//h3")).getText().trim();
		logger.info("Start set day : " + dayInfo + " meeting space");
		
		// Click add event space button
		clickAddEventSpace(rootDiv);

		// Set room type
		setRoomType(rootDiv, eventSpace.getRoomType());

		// Set start time
		setStartTime(rootDiv, DateUtil.toTimeOption(eventSpace.getStartTime()));
		
		// Set end time
		setEndTime(rootDiv, DateUtil.toTimeOption(eventSpace.getEndTime()));

		// Set number of attendee
		setAttendeeNumber(rootDiv, String.valueOf(eventSpace.getAttendeeNumber()));
		
		// Set room size
		setRoomSize(rootDiv, eventSpace.getRoomSize());

	    // Set room setup style
		setRoomSetupStyle(rootDiv, eventSpace.getRoomSetupStyle().value());

		// Set 24hr hold
		setTwentyFourHourHold(rootDiv, eventSpace.isTwentyFourHourHold());
		
		// Set copy all if necessary
		if(eventSpace.getCategory().equals("all")){
			setCopyAll(rootDiv);
		}

		// Save the event space
		clickSaveEventSpace(rootDiv);
		
		logger.info("Set  day : " + dayInfo + " meeting space done");
		return PageLoader.load(RfpEventSpace.class);
	}
	
	public void clickAddEventSpace(WebElement rootDiv){
		WaitUtil waitUtil = new WaitUtil();
		logger.debug("click add button");
		WebElement add = rootDiv.findElement(By.xpath(".//button[contains(@class, 'autotest-gridaction-rfpmeetingroomssubview-rfpmeetingroomsgrid')]"));
		add.click();
		waitUtil.wait(500);
	}
	
	public void clickSaveEventSpace(WebElement rootDiv){
		WaitUtil waitUtil = new WaitUtil();
		logger.debug("Save the event space");
		WebElement save = rootDiv.findElement(By.xpath(".//button[contains(@class,'autotest-ioasaveaction-meetingroommaintenanceform')]"));
		save.click();
		waitUtil.wait(500);
	}
	
	public void setRoomType(WebElement rootDiv, String type){
		logger.debug("Set room type");
		WebElement roomType = rootDiv.findElement(By.xpath(".//div[contains(@class,'autotest-combo-MeetingRoomMaintenanceForm-eventtype')]//input"));
		DropdownMenu roomTypeDropdown = new DropdownMenu(roomType);
		roomTypeDropdown.select(type);
	}
	
	public void setStartTime(WebElement rootDiv, String time){
		logger.debug("Set start time");
		WebElement startTime = rootDiv.findElement(By.xpath(".//div[contains(@class,'autotest-time-MeetingRoomMaintenanceForm-starttime')]//input"));
		DropdownMenu startTimeDropdown = new TimeDropdownMenu(startTime);
		startTimeDropdown.select(time);
	}
	
	public void setEndTime(WebElement rootDiv, String time){
		logger.debug("Set end time");
		WebElement endTime = rootDiv.findElement(By.xpath(".//div[contains(@class,'autotest-time-MeetingRoomMaintenanceForm-endtime')]//input"));
		DropdownMenu endTimeDropdown = new TimeDropdownMenu(endTime);
		endTimeDropdown.select(time);
	}
	
	public void setAttendeeNumber(WebElement rootDiv, String number){
		logger.debug("Set number of attendee");
		WebElement attendee = rootDiv.findElement(By.xpath(".//div[contains(@class,'autotest-integer-MeetingRoomMaintenanceForm-attendeequantity')]//input"));
		attendee.click();
		attendee.clear();
		attendee.sendKeys(number);
	}
	
	public void setRoomSize(WebElement rootDiv, MeetingSpaceInfoType.RoomSize roomSize){
		if(roomSize != null){
			logger.debug("Set room size");
			BigDecimal bigDecimal = roomSize.getSize();
			WebElement roomSizeUnit = rootDiv.findElement(By.xpath(".//div[contains(@class,'autotest-unitType-MeetingRoomMaintenanceForm-size')]//input[contains(@class,'nexus-numberfield')]"));
			roomSizeUnit.clear();
			roomSizeUnit.sendKeys(String.valueOf(bigDecimal));
			WebElement roomSizeType = rootDiv.findElement(By.xpath(".//div[contains(@class,'autotest-unitType-MeetingRoomMaintenanceForm-size')]//input[contains(@class,'nexus-combo')]"));
			DropdownMenu roomSizeTypeDropdown = new DropdownMenu(roomSizeType);
			roomSizeTypeDropdown.select(roomSize.getUnit());
		}
	}
	
	public void setRoomSetupStyle(WebElement rootDiv, String style){
		logger.debug("Set room setup style");
		WebElement rootSetupStyle = rootDiv.findElement(By.xpath(".//div[contains(@class,'autotest-combo-MeetingRoomMaintenanceForm-setuptype')]//input"));
		DropdownMenu rootSetupStyleDropdown = new DropdownMenu(rootSetupStyle);
		rootSetupStyleDropdown.select(style);
	}
	
	public void setTwentyFourHourHold(WebElement rootDiv, boolean hold){
		logger.debug("Set 24hr hold");
		WebElement twentyFour = rootDiv.findElement(By.xpath(".//div[contains(@class,'autotest-checkbox-MeetingRoomMaintenanceForm-hold')]//input"));
		XCheckbox checkbox = new XCheckbox(twentyFour);
		if(hold){
			logger.debug("Set 24 hours hold - ON");
			checkbox.checkON();
		}else{
			logger.debug("Set 24 hours hold - OFF");
			checkbox.checkOFF();
		}
	}
	
	public void setCopyAll(WebElement rootDiv){
		logger.debug("Check on CopyAll");
		WebElement copyAll = rootDiv.findElement(By.xpath(".//div[contains(@class,'autotest-checkbox-MeetingRoomMaintenanceForm-copyeventtoall')]//input"));
		XCheckbox checkbox = new XCheckbox(copyAll);
		checkbox.checkON();
	}
	
	public RfpEventSpace setComment(String comment){
		eventSpaceComment.clear();
		eventSpaceComment.sendKeys(comment);
		return this;
	}
	
	/**
	 * Show additional information
	 * @return
	 */
	public RfpEventSpace showAdditionalInformation(){
		if(getCommentDisplayStatus().contains("hide")){
			additionInformationHeader.click();
			return PageLoader.load(RfpEventSpace.class);
		}else{
			return this;
		}
	}
	/**
	 * Hide additional information
	 * @return
	 */
	public RfpEventSpace hideAdditionalInformation(){
		if(!getCommentDisplayStatus().contains("hide")){
			additionInformationHeader.click();
			return PageLoader.load(RfpEventSpace.class);
		}else{
			return this;
		}
	}
	
	private String getCommentDisplayStatus(){
		WebDriver driver = EnvContext.webDriverTL.get();
		By statusBy = By.cssSelector(".autotest-collapsibleSection-RfpMeetingRoomsSubview-mradditioninfosection .nexus-section-body");
		WebElement div = driver.findElement(statusBy);
		return div.getAttribute("class").trim();
	}
	
	

}
